﻿using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using PMIS.Shared.DTO;
using PMIS.Shared.Models;
using PMIS.WebApi.Model;
using PMIS.WebApi.Services;
using PMIS.WebApi.SnowflakeId;
using System.Linq.Expressions;
using PMIS.WebApi.Common.Attributes;
using SqlSugar;

namespace PMIS.WebApi.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    [Authorize]
    public class UserController : ControllerBase
    {
        private readonly IMapper _mapper;
        private readonly IUserService _service;
        private readonly SnowflakeIdGenerator _idGenerator;

        public UserController(IUserService service, IMapper mapper, SnowflakeIdGenerator idGenerator)
        {
            _service = service;
            _mapper = mapper;
            _idGenerator = idGenerator;
        }

        [HttpPost]
        public async Task<IActionResult> Add(UserDto u)
        {
            var res = new ApiResult();
            if (!ModelState.IsValid)
            {
                return BadRequest(ModelState);
            }
            var user = _mapper.Map<User>(u);
            user.Id = _idGenerator.GetId();
            user.Password = "123456"; //

            if (!string.IsNullOrEmpty(user.Email))
            {
                var count = await _service.QueryEntity(x => x.Email == user.Email).CountAsync();
                if (count > 0)
                {
                    res.code = -1;
                    res.msg = string.Format("已存在邮箱{0}", user.Email);
                    return Ok(res);
                }
            }

            if (!string.IsNullOrEmpty(user.UserName))
            {
                var count = await _service.QueryEntity(x => x.UserName == user.UserName).CountAsync();
                if (count > 0)
                {
                    res.code = -1;
                    res.msg = string.Format("已存在用户名{0}", user.UserName);
                    return Ok(res);
                }
            }

            var data = await _service.AddEntityAsync(user);
            res.data = data;
            return Ok(res);
        }

        [HttpPost]
        public async Task<IActionResult> Delete(List<string> ids)
        {
            var res = new ApiResult();
            var user = (User)HttpContext.Items["User"];
            if (ids.Contains(user.Id))
            {
                res.code = -1;
                res.msg = "不可删除自己";
                return Ok(res);
            }
            var data = await _service.DeleteEntityAsync<User>(x => ids.Contains(x.Id));
            res.data = data;
            return Ok(res);
        }

        [HttpGet]
        public async Task<IActionResult> Get(string id)
        {
            var data = await _service.GetEntityAsync(id);
            var res = new ApiResult() { data = data };
            return Ok(res);
        }

        [HttpPut]
        public async Task<IActionResult> Update(UserDto u)
        {
            var res = new ApiResult();
            var user = _mapper.Map<User>(u);

            if (!string.IsNullOrEmpty(user.Email))
            {
                var count = await _service.QueryEntity(x => x.Email == user.Email).CountAsync();
                if (count > 0)
                {
                    res.code = -1;
                    res.msg = string.Format("已存在邮箱{0}", user.Email);
                    return Ok(res);
                }
            }

            if (!string.IsNullOrEmpty(user.UserName))
            {
                var count = await _service.QueryEntity(x => x.UserName == user.UserName).CountAsync();
                if (count > 0)
                {
                    res.code = -1;
                    res.msg = string.Format("已存在用户名{0}", user.UserName);
                    return Ok(res);
                }
            }

            var ignoreNameList = new List<string>() { "Password", "CreatorId", "CreateTime" };
            var data = await _service.UpdateEntityAsync(user, ignoreNameList);
            res.data = data;
            return Ok(res);
        }

        [HttpGet]
        public async Task<IActionResult> GetList(int? pageNum, int? pageSize, string? name, int? gender)
        {
            Expression<Func<User, bool>> predicate = Expressionable.Create<User>() 
              .AndIF(!string.IsNullOrEmpty(name), u => u.UserName.Contains(name) || u.RealName.Contains(name))
              .AndIF(gender.HasValue, u => u.Gender == gender.Value)
              .ToExpression();

            var data = await _service.GetEntityListAsync(pageNum, pageSize, predicate);
            var res = new ApiResult() { data = data };
            return Ok(res);
        }
    }
}
